]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
appDisplay: Use the desktop file index for app searching
authorJasper St. Pierre <jstpierre@mecheye.net>
Sun, 3 Nov 2013 00:13:42 +0000 (20:13 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Thu, 14 Nov 2013 19:28:52 +0000 (14:28 -0500)
Rather than scanning all apps for searching, use Ryan's new desktop
file index and the glib support APIs for app searching instead of our
own system.

https://bugzilla.gnome.org/show_bug.cgi?id=711631

js/ui/appDisplay.js
src/shell-app-private.h
src/shell-app-system.c
src/shell-app-system.h
src/shell-app-usage.c
src/shell-app-usage.h
src/shell-app.c
src/shell-util.c
src/shell-util.h

index c683cc2ba2abd95efee3db863c2cd487c2115ec2..4785c9981c2f92e70b7de4e75f124da672154c53 100644 (file)
@@ -889,11 +889,24 @@ const AppSearchProvider = new Lang.Class({
     },
 
     getInitialResultSet: function(terms, callback, cancellable) {
-        callback(this._appSys.initial_search(terms));
+        let query = terms.join(' ');
+        let groups = Gio.DesktopAppInfo.search(query);
+        let usage = Shell.AppUsage.get_default();
+        let results = [];
+        groups.forEach(function(group) {
+            group = group.filter(function(appID) {
+                let app = Gio.DesktopAppInfo.new(appID);
+                return app && app.should_show();
+            });
+            results = results.concat(group.sort(function(a, b) {
+                return usage.compare('', a, b);
+            }));
+        });
+        callback(results);
     },
 
     getSubsearchResultSet: function(previousResults, terms, callback, cancellable) {
-        callback(this._appSys.subsearch(previousResults, terms));
+        this.getInitialResultSet(terms, callback, cancellable);
     },
 
     activateResult: function(result) {
index 407e75f20f17eb680645c3656d54d1abd6697173..020abd43272bac6f7ba26131946c0e1c685270f0 100644 (file)
@@ -22,11 +22,6 @@ void _shell_app_add_window (ShellApp *app, MetaWindow *window);
 
 void _shell_app_remove_window (ShellApp *app, MetaWindow *window);
 
-void _shell_app_do_match (ShellApp         *app,
-                          GSList           *terms,
-                          GSList          **prefix_results,
-                          GSList          **substring_results);
-
 G_END_DECLS
 
 #endif /* __SHELL_APP_PRIVATE_H__ */
index feca09cf86200f700e8cdd99cccaed69c424ee80..3a31709254ceba3d2d18a48ca4cf488ed87a072e 100644 (file)
@@ -348,143 +348,3 @@ shell_app_system_get_running (ShellAppSystem *self)
 
   return ret;
 }
-
-
-static gint
-compare_apps_by_usage (gconstpointer a,
-                       gconstpointer b,
-                       gpointer      data)
-{
-  ShellAppUsage *usage = shell_app_usage_get_default ();
-
-  ShellApp *app_a = (ShellApp*)a;
-  ShellApp *app_b = (ShellApp*)b;
-
-  return shell_app_usage_compare (usage, "", app_a, app_b);
-}
-
-static GSList *
-sort_and_concat_results (ShellAppSystem *system,
-                         GSList         *prefix_matches,
-                         GSList         *substring_matches)
-{
-  GSList *matches = NULL;
-  GSList *l;
-
-  prefix_matches = g_slist_sort_with_data (prefix_matches,
-                                           compare_apps_by_usage,
-                                           system);
-  substring_matches = g_slist_sort_with_data (substring_matches,
-                                              compare_apps_by_usage,
-                                              system);
-
-  for (l = substring_matches; l != NULL; l = l->next)
-    matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
-  for (l = prefix_matches; l != NULL; l = l->next)
-    matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
-
-  return g_slist_reverse (matches);
-}
-
-/**
- * normalize_terms:
- * @terms: (element-type utf8): Input search terms
- *
- * Returns: (element-type utf8) (transfer full): Unicode-normalized and lowercased terms
- */
-static GSList *
-normalize_terms (GSList *terms)
-{
-  GSList *normalized_terms = NULL;
-  GSList *iter;
-  for (iter = terms; iter; iter = iter->next)
-    {
-      const char *term = iter->data;
-      normalized_terms = g_slist_prepend (normalized_terms,
-                                          shell_util_normalize_casefold_and_unaccent (term));
-    }
-  return normalized_terms;
-}
-
-static GSList *
-search_tree (ShellAppSystem *self,
-             GSList         *terms,
-             GHashTable     *apps)
-{
-  GSList *prefix_results = NULL;
-  GSList *substring_results = NULL;
-  GSList *normalized_terms;
-  GHashTableIter iter;
-  gpointer key, value;
-
-  normalized_terms = normalize_terms (terms);
-
-  g_hash_table_iter_init (&iter, apps);
-  while (g_hash_table_iter_next (&iter, &key, &value))
-    {
-      ShellApp *app = value;
-      _shell_app_do_match (app, normalized_terms,
-                           &prefix_results,
-                           &substring_results);
-    }
-  g_slist_free_full (normalized_terms, g_free);
-
-  return sort_and_concat_results (self, prefix_results, substring_results);
-}
-
-/**
- * shell_app_system_initial_search:
- * @system: A #ShellAppSystem
- * @terms: (element-type utf8): List of terms, logical AND
- *
- * Search through applications for the given search terms.
- *
- * Returns: (transfer container) (element-type utf8): List of applications
- */
-GSList *
-shell_app_system_initial_search (ShellAppSystem  *self,
-                                 GSList          *terms)
-{
-  return search_tree (self, terms, self->priv->id_to_app);
-}
-
-/**
- * shell_app_system_subsearch:
- * @system: A #ShellAppSystem
- * @previous_results: (element-type utf8): List of previous results
- * @terms: (element-type utf8): List of terms, logical AND
- *
- * Search through a previous result set; for more information, see
- * js/ui/search.js. Note that returned strings are only valid until
- * a return to the main loop.
- *
- * Returns: (transfer container) (element-type utf8): List of application identifiers
- */
-GSList *
-shell_app_system_subsearch (ShellAppSystem   *system,
-                            GSList           *previous_results,
-                            GSList           *terms)
-{
-  GSList *iter;
-  GSList *prefix_results = NULL;
-  GSList *substring_results = NULL;
-  GSList *normalized_terms = normalize_terms (terms);
-
-  previous_results = g_slist_reverse (previous_results);
-
-  for (iter = previous_results; iter; iter = iter->next)
-    {
-      ShellApp *app = shell_app_system_lookup_app (system, iter->data);
-
-      _shell_app_do_match (app, normalized_terms,
-                           &prefix_results,
-                           &substring_results);
-    }
-  g_slist_free_full (normalized_terms, g_free);
-
-  /* Note that a shorter term might have matched as a prefix, but
-     when extended only as a substring, so we have to redo the
-     sort rather than reusing the existing ordering */
-  return sort_and_concat_results (system, prefix_results, substring_results);
-}
-
index 6f9344925d9a68e6c09bc3c35b6474e7470df4f0..c0c501ad7a0259acdbed8a34138a3d3acc11e741 100644 (file)
@@ -49,10 +49,4 @@ ShellApp       *shell_app_system_lookup_desktop_wmclass       (ShellAppSystem *s
 
 GSList         *shell_app_system_get_running               (ShellAppSystem  *self);
 
-GSList         *shell_app_system_initial_search            (ShellAppSystem  *system,
-                                                            GSList          *terms);
-GSList         *shell_app_system_subsearch                 (ShellAppSystem  *system,
-                                                            GSList          *previous_results,
-                                                            GSList          *terms);
-
 #endif /* __SHELL_APP_SYSTEM_H__ */
index 31e7f85c276beede687864886a7ea4cf64ee2b97..c733ce4c52634af897221f06d4b6971165afd6d0 100644 (file)
@@ -527,19 +527,19 @@ shell_app_usage_get_most_used (ShellAppUsage   *self,
  * shell_app_usage_compare:
  * @self: the usage instance to request
  * @context: Activity identifier
- * @app_a: First app
- * @app_b: Second app
+ * @id_a: ID of first app
+ * @id_b: ID of second app
  *
- * Compare @app_a and @app_b based on frequency of use.
+ * Compare @id_a and @id_b based on frequency of use.
  *
- * Returns: -1 if @app_a ranks higher than @app_b, 1 if @app_b ranks higher
- *          than @app_a, and 0 if both rank equally.
+ * Returns: -1 if @id_a ranks higher than @id_b, 1 if @id_b ranks higher
+ *          than @id_a, and 0 if both rank equally.
  */
 int
 shell_app_usage_compare (ShellAppUsage *self,
                          const char    *context,
-                         ShellApp      *app_a,
-                         ShellApp      *app_b)
+                         const char    *id_a,
+                         const char    *id_b)
 {
   GHashTable *usages;
   UsageData *usage_a, *usage_b;
@@ -548,8 +548,8 @@ shell_app_usage_compare (ShellAppUsage *self,
   if (usages == NULL)
     return 0;
 
-  usage_a = g_hash_table_lookup (usages, shell_app_get_id (app_a));
-  usage_b = g_hash_table_lookup (usages, shell_app_get_id (app_b));
+  usage_a = g_hash_table_lookup (usages, id_a);
+  usage_b = g_hash_table_lookup (usages, id_b);
 
   if (usage_a == NULL && usage_b == NULL)
     return 0;
index 4016b58c5f8bd6f8d8ecea37877b51eed714642a..4afdbb3ec60a6f75abc6752259f2c02ebafc6c12 100644 (file)
@@ -31,8 +31,8 @@ GSList *shell_app_usage_get_most_used (ShellAppUsage *usage,
                                        const char    *context);
 int shell_app_usage_compare (ShellAppUsage *self,
                              const char    *context,
-                             ShellApp      *app_a,
-                             ShellApp      *app_b);
+                             const char    *id_a,
+                             const char    *id_b);
 
 G_END_DECLS
 
index 6904b6b6bfb914363562ea4fe113e016c466992c..487268d1f7aeaf6772ea497f707068dc0f7cac3c 100644 (file)
@@ -81,12 +81,7 @@ struct _ShellApp
   ShellAppRunningState *running_state;
 
   char *window_id_string;
-
-  char *casefolded_name;
-  char *casefolded_generic_name;
   char *name_collation_key;
-  char *casefolded_exec;
-  char **casefolded_keywords;
 };
 
 enum {
@@ -1360,49 +1355,6 @@ trim_exec_line (const char *str)
   return g_strndup (start, end - start);
 }
 
-static void
-shell_app_init_search_data (ShellApp *app)
-{
-  const char *name;
-  const char *generic_name;
-  const char *exec;
-  const char * const *keywords;
-  char *normalized_exec;
-
-  name = g_app_info_get_name (G_APP_INFO (app->info));
-  app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name);
-
-  generic_name = g_desktop_app_info_get_generic_name (app->info);
-  if (generic_name)
-    app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name);
-  else
-    app->casefolded_generic_name = NULL;
-
-  exec = g_app_info_get_executable (G_APP_INFO (app->info));
-  normalized_exec = shell_util_normalize_casefold_and_unaccent (exec);
-  app->casefolded_exec = trim_exec_line (normalized_exec);
-  g_free (normalized_exec);
-
-  keywords = g_desktop_app_info_get_keywords (app->info);
-
-  if (keywords)
-    {
-      int i;
-
-      app->casefolded_keywords = g_new0 (char*, g_strv_length ((char **)keywords) + 1);
-
-      i = 0;
-      while (keywords[i])
-        {
-          app->casefolded_keywords[i] = shell_util_normalize_casefold_and_unaccent (keywords[i]);
-          ++i;
-        }
-      app->casefolded_keywords[i] = NULL;
-    }
-  else
-    app->casefolded_keywords = NULL;
-}
-
 /**
  * shell_app_compare_by_name:
  * @app: One app
@@ -1419,116 +1371,6 @@ shell_app_compare_by_name (ShellApp *app, ShellApp *other)
   return strcmp (app->name_collation_key, other->name_collation_key);
 }
 
-static ShellAppSearchMatch
-_shell_app_match_search_terms (ShellApp  *app,
-                               GSList    *terms)
-{
-  GSList *iter;
-  ShellAppSearchMatch match;
-
-  if (G_UNLIKELY (!app->casefolded_name))
-    shell_app_init_search_data (app);
-
-  match = MATCH_NONE;
-  for (iter = terms; iter; iter = iter->next)
-    {
-      ShellAppSearchMatch current_match;
-      const char *term = iter->data;
-      const char *p;
-
-      current_match = MATCH_NONE;
-
-      p = strstr (app->casefolded_name, term);
-      if (p != NULL)
-        {
-          if (p == app->casefolded_name || *(p - 1) == ' ')
-            current_match = MATCH_PREFIX;
-          else
-            current_match = MATCH_SUBSTRING;
-        }
-
-      if (app->casefolded_generic_name)
-        {
-          p = strstr (app->casefolded_generic_name, term);
-          if (p != NULL)
-            {
-              if (p == app->casefolded_generic_name || *(p - 1) == ' ')
-                current_match = MATCH_PREFIX;
-              else if (current_match < MATCH_PREFIX)
-                current_match = MATCH_SUBSTRING;
-            }
-        }
-
-      if (app->casefolded_exec)
-        {
-          p = strstr (app->casefolded_exec, term);
-          if (p != NULL)
-            {
-              if (p == app->casefolded_exec || *(p - 1) == '-')
-                current_match = MATCH_PREFIX;
-              else if (current_match < MATCH_PREFIX)
-                current_match = MATCH_SUBSTRING;
-            }
-        }
-
-      if (app->casefolded_keywords)
-        {
-          int i = 0;
-          while (app->casefolded_keywords[i] && current_match < MATCH_PREFIX)
-            {
-              p = strstr (app->casefolded_keywords[i], term);
-              if (p != NULL)
-                {
-                  if (p == app->casefolded_keywords[i])
-                    current_match = MATCH_PREFIX;
-                  else
-                    current_match = MATCH_SUBSTRING;
-                }
-              ++i;
-            }
-        }
-
-      if (current_match == MATCH_NONE)
-        return current_match;
-
-      if (current_match > match)
-        match = current_match;
-    }
-  return match;
-}
-
-void
-_shell_app_do_match (ShellApp         *app,
-                     GSList           *terms,
-                     GSList          **prefix_results,
-                     GSList          **substring_results)
-{
-  ShellAppSearchMatch match;
-
-  g_assert (app != NULL);
-
-  /* Skip window-backed apps */ 
-  if (app->info == NULL)
-    return;
-  /* Skip not-visible apps */ 
-  if (!g_app_info_should_show (G_APP_INFO (app->info)))
-    return;
-
-  match = _shell_app_match_search_terms (app, terms);
-  switch (match)
-    {
-      case MATCH_NONE:
-        break;
-      case MATCH_PREFIX:
-        *prefix_results = g_slist_prepend (*prefix_results, app);
-        break;
-      case MATCH_SUBSTRING:
-        *substring_results = g_slist_prepend (*substring_results, app);
-        break;
-    }
-}
-
-
 static void
 shell_app_init (ShellApp *self)
 {
@@ -1561,11 +1403,7 @@ shell_app_finalize (GObject *object)
 
   g_free (app->window_id_string);
 
-  g_free (app->casefolded_name);
-  g_free (app->casefolded_generic_name);
   g_free (app->name_collation_key);
-  g_free (app->casefolded_exec);
-  g_strfreev (app->casefolded_keywords);
 
   G_OBJECT_CLASS(shell_app_parent_class)->finalize (object);
 }
index 92fc3dad62b8656c65f7ecfb642a67238d28f3fa..bbbb86fcbba38b0cd4b4a0c002d2c11a9317a758 100644 (file)
@@ -111,98 +111,6 @@ shell_util_get_transformed_allocation (ClutterActor    *actor,
   box->y2 = y_max;
 }
 
-char *
-shell_util_normalize_and_casefold (const char *str)
-{
-  char *normalized, *result;
-
-  if (str == NULL)
-    return NULL;
-
-  /* NOTE: 'ALL' is equivalent to 'NFKD'. If this is ever updated, please
-   * update the unaccenting mechanism as well. */
-  normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
-  result = g_utf8_casefold (normalized, -1);
-  g_free (normalized);
-  return result;
-}
-
-/* Combining diacritical mark?
- *  Basic range: [0x0300,0x036F]
- *  Supplement:  [0x1DC0,0x1DFF]
- *  For Symbols: [0x20D0,0x20FF]
- *  Half marks:  [0xFE20,0xFE2F]
- */
-#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F)  || \
-                        ((c) >= 0x1DC0 && (c) <= 0x1DFF)  || \
-                        ((c) >= 0x20D0 && (c) <= 0x20FF)  || \
-                        ((c) >= 0xFE20 && (c) <= 0xFE2F))
-
-/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
- * Originally written by Aleksander Morgado <aleksander@gnu.org>
- */
-char *
-shell_util_normalize_casefold_and_unaccent (const char *str)
-{
-  char *tmp;
-  gsize i = 0, j = 0, ilen;
-
-  if (str == NULL)
-    return NULL;
-
-  /* Get the NFKD-normalized and casefolded string */
-  tmp = shell_util_normalize_and_casefold (str);
-  ilen = strlen (tmp);
-
-  while (i < ilen)
-    {
-      gunichar unichar;
-      gchar *next_utf8;
-      gint utf8_len;
-
-      /* Get next character of the word as UCS4 */
-      unichar = g_utf8_get_char_validated (&tmp[i], -1);
-
-      /* Invalid UTF-8 character or end of original string. */
-      if (unichar == (gunichar) -1 ||
-          unichar == (gunichar) -2)
-        {
-          break;
-        }
-
-      /* Find next UTF-8 character */
-      next_utf8 = g_utf8_next_char (&tmp[i]);
-      utf8_len = next_utf8 - &tmp[i];
-
-      if (IS_CDM_UCS4 ((guint32) unichar))
-        {
-          /* If the given unichar is a combining diacritical mark,
-           * just update the original index, not the output one */
-          i += utf8_len;
-          continue;
-        }
-
-      /* If already found a previous combining
-       * diacritical mark, indexes are different so
-       * need to copy characters. As output and input
-       * buffers may overlap, need to use memmove
-       * instead of memcpy */
-      if (i != j)
-        {
-          memmove (&tmp[j], &tmp[i], utf8_len);
-        }
-
-      /* Update both indexes */
-      i += utf8_len;
-      j += utf8_len;
-    }
-
-  /* Force proper string end */
-  tmp[j] = '\0';
-
-  return tmp;
-}
-
 /**
  * shell_util_format_date:
  * @format: a strftime-style string format, as parsed by
index 95271d05a436bcb0f773a2101f1a6c91f9f412e1..fdaec560acab49f21f2937caac52f78ae5583e81 100644 (file)
@@ -19,10 +19,6 @@ void     shell_util_get_transformed_allocation (ClutterActor     *actor,
 
 int      shell_util_get_week_start             (void);
 
-char    *shell_util_normalize_and_casefold     (const char       *str);
-
-char    *shell_util_normalize_casefold_and_unaccent (const char  *str);
-
 char    *shell_util_format_date                (const char       *format,
                                                 gint64            time_ms);